package com.yupi.project.controller;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.yupi.project.common.BaseResponse;
import com.yupi.project.common.ErrorCode;
import com.yupi.project.common.ResultUtils;
import com.yupi.project.exception.BusinessException;
import com.yupi.project.service.EmailService;
import com.yupi.project.util.SendEmailUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

/**
 * @author <a href=""https://github.com/Fzs0>逢左使</a>
 * @create 2023/12/25 11:07
 * @Description: 邮件验证码接口
 */

@RestController
@RequestMapping("/email")
@Api(tags = "邮件验证码")
@Slf4j
public class EmailController {

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Value("${rabbitmq.exchange}")
    private String exchangeName;

    @Value("${rabbitmq.routingKey}")
    private String routingKey;

    @Value("${rabbitmq.bind.dead.exchange}")
    private String commonExchange;

    @Value("${rabbitmq.bind.dead.routingKey}")
    private String commonRoutingKey;

    /**
     * redis缓存邮箱验证码
     */
    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private EmailService emailService;

    /**
     * 邮箱验证码缓存
     */
    private final String CACHE_CODE = "code_cache";

    /**
     * 发送邮件验证码
     * @param email 目标邮箱
     * @return
     */
    @PostMapping("/sendCode")
    @ApiOperation(value = "sendCode") //  用于描述单个接口的信息，包括接口的名称、描述、HTTP 方法等
    @ApiOperationSupport(order = 1) // 指定接口的排序顺序
    public BaseResponse<String> sendCode(@RequestParam String email) {
        // 根据邮箱随机生产一个验证码
        String code = SendEmailUtil.sendEmail(email);
        rabbitTemplate.convertAndSend(exchangeName, routingKey, code);
        // 发送到死信队列中
        rabbitTemplate.convertAndSend(commonExchange, commonRoutingKey, code);
        // 放入redis缓存中
        // 存储 60秒
        redisTemplate.opsForValue().set(CACHE_CODE, code, 60, TimeUnit.SECONDS);
        // 把验证码返回去
        return ResultUtils.success(code);
    }

    /**
     * 压力测试接口
     * @param message
     * @return
     */
    @PostMapping("/sendMessage")
    @ApiOperation(value = "sendMessage")
    public BaseResponse<String> sendMessage(@RequestParam String message) {
        // 发送信息
        rabbitTemplate.convertAndSend(exchangeName, routingKey, message);
        // 发送到死信队列中
        rabbitTemplate.convertAndSend(commonExchange, commonRoutingKey, message);
        return ResultUtils.success(message);
    }

    /**
     * 进行邮箱验证码登录
     * @param code 前端传入的验证码
     * @return
     */
    @PostMapping("/login")
    @ApiOperation(value = "emailLogin")
    @ApiOperationSupport(order = 2)
    public BaseResponse<Boolean> emailLogin(@RequestParam String code, @RequestParam String email, HttpServletRequest request) {
        // todo 虽然可以登录 但是需要验证userState 所以得有一个临时账号给用户 或者用邮箱就算注册成功
        String cache_code = (String) redisTemplate.opsForValue().get(CACHE_CODE);
        // 验证码不存在或者到期
        if (cache_code == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 验证码错误
        if (!code.equals(cache_code)) {
            throw new BusinessException(ErrorCode.CODE_ERROR);
        }

        // 删除验证码
        redisTemplate.delete(CACHE_CODE);
        emailService.userLoginByEmail(email, request);
        // 把验证码返回去
        return ResultUtils.success(true);
    }


}
